/*
 * =====================================================================================
 *
 *       Filename:  vm.h
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  02/23/12 09:29:00
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  randyli (randy), randyli@tencent.com
 *        Company:  Tencent
 *
 * =====================================================================================
 */


#ifndef  VM_INC
#define  VM_INC
#define __DEBUG
/* opcode */
#define OP_NOP   0
#define OP_ILOAD 10
#define OP_FLOAD 11
#define OP_SLOAD 12
#define OP_LOAD  1
#define OP_STORE 20
#define OP_NEG   30
#define OP_PLUS  40
#define OP_MINUS 50
#define OP_TIMES 60
#define OP_DIV   70
#define OP_MOD   71
#define OP_AND   72
#define OP_OR    73
#define OP_GT  80
#define OP_GE  90
#define OP_LT  100
#define OP_LE  110
#define OP_EQ  111
#define OP_NE  112
#define OP_NOT  113
#define OP_IFGOTO  120
#define OP_ECHO  130
#define OP_CALL  140
#define OP_RET   150
#define OP_JMP   151
#define OP_FETCH 152
#define OP_FETCH2 153

typedef struct _object{
	int type;
	union
	{
		int  i;
		float  f;
		char *s;
		void *o;
	}val;
}object;

typedef enum {INT,FLOAT,STRING, ARRAY}objtype;

#define typeof(obj) ((obj).type)
#define ivalue(obj) ((obj).val.i)
#define fvalue(obj) ((obj).val.f)
#define svalue(obj) ((obj).val.s)
#define ovalue(obj) ((obj).val.o)
#define val(obj) ((obj).val)

typedef struct _opcode{
	int  op;
	object arg1;
	object arg2;
	object arg3;
}opcode; 

#include "array.h"
typedef void (*sys_call) (void*);

typedef struct _sys_call_item
{
	char name[32];
	sys_call func;
}sys_call_item;

typedef struct _svm
{
	object* stack; //exe stack
	int  sp;//stack pointer
	int  ip;// instruction pointer
	int  bp;//bp register
	smt_array* sys_calls;
}svm;

typedef struct _exe
{
	opcode* ops; 
	int ops_num; //how many opcode
	int start;   //where start 
	int ntmp;	
	char* sconst;  //the constant strings 
}exe;

int op_dump(opcode* ops, int ops_num);
int svm_new(svm** vm);
int svm_run(svm* vm, exe* e);
int svm_destroy(svm* vm);

typedef struct _setting
{
	int dump_opcode;
}setting;
extern setting settings;
#endif   /* ----- #ifndef VM_INC  ----- */
